package com.bugsnag.ohos;

import ohos.aafwk.ability.ProcessErrorInfo;
import ohos.app.Context;
import ohos.app.IAbilityManager;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.eventhandler.InnerEvent;

import com.bugsnag.ohos.util.OhosLog;

import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @since 2021-07-19
 */
public class AnrDetailsCollector {

    private static final Long INFO_POLL_THRESHOLD_MS = 100L;
    private static final int MAX_ATTEMPTS = 300;
    private EventRunner runner = EventRunner.create();
    private MyHandler handler = new MyHandler(runner);



    public ProcessErrorInfo collectAnrDetails(Context ctx) {
        IAbilityManager am = ctx.getAbilityManager();
        OhosLog.d("AnrPlugin", "collectAnrDetails() am = %s",am);
        return am != null ? captureProcessErrorState(am, ctx.getProcessInfo().getPid()) : null;
    }

    /**
     * Collects information about an ANR, by querying an activity manager for information about
     * any proceses which are currently in an error condition.
     * <p>
     *
     */
    public ProcessErrorInfo captureProcessErrorState(IAbilityManager am, int pid) {
        if (am != null) {
            List<ProcessErrorInfo> errorInfoList = am.getProcessesErrorInfo();
            if (errorInfoList != null && errorInfoList.size() > 0) {
                for (ProcessErrorInfo processErrorInfo : errorInfoList) {
                    if (processErrorInfo.getPid() == pid) {
                        return processErrorInfo;
                    }
                }
            } else {
                return null;
            }
        }
        return null;
    }

    public void addErrorStateInfo(Event event, ProcessErrorInfo anrState) {
        String msg = anrState.getShortMsg();

        if (!event.getErrors().isEmpty()) {
            if (msg.startsWith("ANR")) {
                msg.replace("ANR", "");
            }
            event.getErrors().get(0).setErrorMessage(msg);
        }
    }


    public void collectAnrErrorDetails(Client client, Event event) {
        OhosLog.d("AnrPlugin", "collectAnrErrorDetails()");
        AtomicInteger attempts = new AtomicInteger();
        handler.postTask(new Runnable() {
            @Override
            public void run() {
                ProcessErrorInfo anrDetails = collectAnrDetails(client.appContext);
                if (anrDetails == null) {
                  //  int count = attempts.getAndIncrement();
                 //   OhosLog.d("AnrPlugin", "attempts.getAndIncrement(): %d",count);
                //    if (count < MAX_ATTEMPTS) {
                        handler.postTimingTask(this, INFO_POLL_THRESHOLD_MS);
                //    }
                } else {
                    OhosLog.d("AnrPlugin", "anrDetails != null ; go method client.populateAndNotifyOhosEvent()");
                    addErrorStateInfo(event, anrDetails);
                    client.populateAndNotifyOhosEvent(event, null);
                }
            }
        });
    }

    static class MyHandler extends EventHandler {
        public MyHandler(EventRunner runner) throws IllegalArgumentException {
            super(runner);
        }

        @Override
        protected void processEvent(InnerEvent event) {
            super.processEvent(event);
        }
    }

}
